/**********************************************************************************
Name:  EDCCalculationController
Copyright © 2012  Lodha Group
===================================================================================
===================================================================================
Purpose:
-------
Controller For Calculating EDC for Opportunity
===================================================================================
===================================================================================
History
-------
VERSION    AUTHOR                DATE             DETAIL              
1.0 -   CG Dev Team          28/05/2012      INITIAL DEVELOPMENT
**********************************************************************************/

public class EDCCalculationController {

    EDC_for_opportunity__c edcVO{get;set;}
    Integer edcfromcreateddate{get;set;}
    Integer edcfromvisitddate{get;set;}
    Integer upperedc{get;set;}
    Integer callattemptlimit{get;set;}
    Integer callattemptedc{get;set;}        
    public static boolean isinsert=false;
    public static boolean isFirstUpdate=true;  

               
/*********************************************************************
    Purpose     : To get mappig values from custom settings for EDC 
    Parameters  : String projecttype
    Returns     : None
**********************************************************************/  
    public void EDCVOlist(String projecttype){
          
      try{
            edcVO=[select id,Project_Type__c,EDC_from_Created_date__c,EDC_from_Visit_date__c,Upper_Limit__c,Call_Attempt_Limit__c,
            Call_Attempt_EDC__c from EDC_for_opportunity__c where Project_Type__c=:projecttype];                      
            edcfromcreateddate=Integer.valueof(edcVO.EDC_from_Created_date__c);
            edcfromvisitddate=Integer.valueof(edcVO.EDC_from_Visit_date__c);
            upperedc=Integer.valueof(edcVO.Upper_Limit__c);
            callattemptlimit=Integer.valueof(edcVO.Call_Attempt_Limit__c);
            callattemptedc=Integer.valueof(edcVO.Call_Attempt_EDC__c);
       }catch(Exception  e){
       
       }
    }
    
/**********************************************************************
    Purpose     : To update EDC and upper EDC before Opportunity insert.
    Parameters  : List of Opportunity(Trigger.New)
    Returns     : None
**********************************************************************/   
    public void CalculateEDCbeforeinsert(List<Opportunity> opportunitylist){
    
    try{
       if(!opportunitylist.IsEmpty()){ 
          Map<id,Project_Name__c>  projectmap=new Map<id,Project_Name__c>([select id,Project_Type__c from Project_Name__c where id!=null]);           
             
             for(Opportunity opplist: opportunitylist){ 
                       EDCVOlist(projectmap.get(opplist.Project_Name__c).Project_Type__c);  
                       opplist.CloseDate=System.Today().addDays(edcfromcreateddate);
                       opplist.Upper_EDC__c=System.Today().addDays(upperedc);
                       opplist.Current_EDC__c=opplist.CloseDate;

             }
         }  
      }catch(Exception e){
      }         
 }
    
/**********************************************************************
    Purpose     : To update EDC and upper EDC after Opp insert 
    Parameters  : List of Opportunity(Trigger.New,Trigger.oldmap)
    Returns     : None
**********************************************************************/    
    public void CalculateEDC(List<Opportunity> opportunitylist,Map<Id,Opportunity> opportunityoldmap){                
        
        
         
       if(!opportunitylist.IsEmpty()){ 
       
           Map<id,Project_Name__c>  projectmap=new Map<id,Project_Name__c>([select id,Project_Type__c from Project_Name__c where id!=null]);
                                             
           for(Opportunity opplist: opportunitylist){ 
                              
                  EDCVOlist(projectmap.get(opplist.Project_Name__c).Project_Type__c); 
                  String oldprojectname;
                  Date oldDoV;
                  Date oldEDC;
                  oldEDC=opportunityoldmap.get(opplist.id).CloseDate;
                  
                  if(opportunityoldmap.get(opplist.id)!=null){
                      oldprojectname=opportunityoldmap.get(opplist.id).Project_Name__c;
                      oldDoV=opportunityoldmap.get(opplist.id).Date_of_Visit__c;
                  }
                opplist.Current_EDC__c=opplist.CloseDate;
                if((opplist.IsActive__c!=true) &&(opplist.CloseDate>=System.today())){
                    opplist.IsActive__c=true;
                }                                                       
                if(opplist.Project_Name__c==oldprojectname)
                {
                    system.debug('Inside same project');
                    if(opplist.Date_of_Visit__c!=null){                          
                         if(opplist.Date_of_Visit__c!=oldDoV){           
                             opplist.CloseDate=opplist.Date_of_Visit__c.addDays(edcfromvisitddate);
                             opplist.Upper_EDC__c=opplist.Date_of_Visit__c.addDays(upperedc); 
                             opplist.Current_EDC__c=opplist.CloseDate;
                             system.debug('Inside same project EDC updated');
                             }                            
                       }
                       if(opplist.CloseDate<oldEDC){
                       
                           Trigger.New[0].addError('EDC value cannot be decreased.');
                       }
                  
                  }else{
                       system.debug('Insidechangedproject');
                       opplist.Updated_by_visit_date__c=false;
                      if(opplist.Date_of_Visit__c!=null){
                           if(opplist.Date_of_Visit__c!=oldDoV){   
                             opplist.CloseDate=opplist.Date_of_Visit__c.addDays(edcfromvisitddate);
                             opplist.Upper_EDC__c=opplist.Date_of_Visit__c.addDays(upperedc); 
                             opplist.Current_EDC__c=opplist.CloseDate;
                             opplist.Updated_by_created_date__c=true;
                             system.debug('InsidechangedprojectDate_of_Visit__c' +opplist.Date_of_Visit__c);
                           }
                           else if(opplist.Updated_by_visit_date__c!=true){
                               opplist.CloseDate=opplist.Date_of_Visit__c.addDays(edcfromvisitddate);
                               opplist.Upper_EDC__c=opplist.Date_of_Visit__c.addDays(upperedc); 
                               opplist.Current_EDC__c=opplist.CloseDate;
                               opplist.Updated_by_visit_date__c=true;
                               system.debug('InsidechangedprojectUpdated_by_visit_date__c' +opplist.Updated_by_visit_date__c);
                           }
                      }else {
                              opplist.Updated_by_created_date__c=false;
                           if(opplist.Updated_by_created_date__c!=true){
                                 opplist.CloseDate=opportunityoldmap.get(opplist.id).createddate.date().addDays(edcfromcreateddate);
                                 opplist.Upper_EDC__c=opportunityoldmap.get(opplist.id).createddate.date().addDays(upperedc); 
                                 opplist.Current_EDC__c=opplist.CloseDate;
                                 opplist.Updated_by_created_date__c=true;
                                 system.debug('InsidechangedprojectUpdated_by_created_date__c' +opplist.Updated_by_created_date__c);
                          }
                      }
                  
                  }
                                                                                                                                                      
                  /*if(opplist.StageName =='Closed Won' && opplist.Amount!=null && opplist.Booking_Date__c!=null){ 
                  system.debug('InsidechangeClosed Won');                     
                      opplist.IsActive__c=false;
                  }else if(opplist.StageName == 'Cancelled' && opplist.Amount!=null && opplist.Date_Of_Cancellation__c!=null){                    
                      opplist.IsActive__c=false;  
                        
                  } */                      
           }
       }
    
    }

    
/***********************************************************************
    Purpose     : To update EDC and upper EDC after Call attempt insert
    Parameters  : List of Call_Attempts__c (Trigger.New)
    Returns     : None
*************************************************************************/   
   public void CalculateEDCaftercallattemptinsert(List<Call_Attempts__c> callattemptlist){           
        
        set<Id> oppids=new set<Id>();
        List<Opportunity> opportunityupdatelist=new List<Opportunity>();
     try{
        if(!callattemptlist.IsEmpty()){
        for(Call_Attempts__c attemptIds: callattemptlist)
            {
                oppids.add(attemptIds.Opportunity__c);
            }
            Map<id,Opportunity>  opportunitymap=new Map<id,Opportunity>([select id,CloseDate,Project_Name__r.Project_Type__c,Last_Call_Date_RO__c,Upper_EDC__c from Opportunity where IsActive__c=true and id in: oppids]);
            
            if(!opportunitymap.IsEmpty()){
            for(Call_Attempts__c attemptlist: callattemptlist){            
                EDCVOlist(opportunitymap.get(attemptlist.Opportunity__c).Project_Name__r.Project_Type__c); 
                               
                Integer differenceindays=(opportunitymap.get(attemptlist.Opportunity__c).Last_Call_Date_RO__c.date()).daysBetween(opportunitymap.get(attemptlist.Opportunity__c).CloseDate);
             
               system.debug('differenceindays: '+differenceindays);
               
              if(differenceindays<=callattemptlimit&&(attemptlist.Call_Attempt_Status__c=='Visit Confirmed'||attemptlist.Call_Attempt_Status__c=='Visit Proposed')){
                 opportunity opp=new opportunity();
                 opp=opportunitymap.get(attemptlist.Opportunity__c);                   
                 opp.CloseDate=attemptlist.Proposed_Date_of_Visit__c.date().addDays(callattemptedc);
                 opp.Current_EDC__c=opp.CloseDate;
                 
              if(opp.CloseDate>opp.Upper_EDC__c){
                 opp.Upper_EDC__c=attemptlist.Proposed_Date_of_Visit__c.date().addDays(callattemptedc);  
                 }
                  opportunityupdatelist.add(opp);
               }
               
            }
          }
                update opportunityupdatelist;
        }
      }catch(Exception e){
      }
    }
    
/***********************************************************************
    Purpose     : To Check for Active Opportunity
    Parameters  : List of Opportunity(Trigger.New)
    Returns     : None
*************************************************************************/  
    public void CheckforActiveOpp(List<Opportunity> opportunitylist, String operation){                
        
        Set<Id> accountId=new Set<Id>();
        Set<Id> projectnameId=new Set<Id>();
        Set<Id> opportunityId=new Set<Id>();
        Boolean isbatchstarted=null;
      try{  
      

        
           for(Opportunity opp:opportunitylist){
           
               opportunityId.add(opp.Id);
               accountId.add(opp.AccountId);
               projectnameId.add(opp.Project_Name__c);
               isbatchstarted=opp.Is_Batch__c;
               
           }                   
       
          if(!isbatchstarted){
           List<Opportunity> activeopplist=[select id,Multiple_Booking__c,Oasys_Flat_Code__c,StageName,Amount,Booking_Date__c,Date_Of_Cancellation__c,LastModifiedDate,Createddate from Opportunity where AccountId in:accountId 
           and Project_Name__c in:projectnameId and id NOT IN:opportunityId and IsActive__c=true];
                     system.debug('activeopplist '+activeopplist);  
           for(Opportunity activeopp: activeopplist){           
                             
               if(operation=='Insert'){
               
                   if((activeopp.Oasys_Flat_Code__c==null && activeopp.Multiple_Booking__c==false)&& (activeopp.StageName!='Closed Won' && activeopp.Amount==null && activeopp.Booking_Date__c==null)&&(activeopp.StageName != 'Cancelled' && activeopp.Amount==null && activeopp.Date_Of_Cancellation__c==null))
                       {
                        Trigger.New[0].addError('An active opportunity exists for the same project.');
                       }
                 }else 
                     {            
                         system.debug('@@Inside ELSE'+activeopp.LastModifiedDate.date()+'******'+(operation=='Update')); 
                         system.debug('&&'+(activeopp.Createddate>=date.parse('24/07/2012')));            
                        if((operation=='Update')&& activeopp.Createddate.date()>=date.parse('24/07/2012')){
                        
                            system.debug('@@LASTMODI');
                        if((activeopp.Oasys_Flat_Code__c!=null && activeopp.Multiple_Booking__c==true)||(activeopp.StageName=='Closed Won' && activeopp.Amount!=null && activeopp.Booking_Date__c!=null)||(activeopp.StageName=='Cancelled'  && activeopp.Amount!=null && activeopp.Date_Of_Cancellation__c!=null))
                           {
                            
                           }else{
                           
                               Trigger.New[0].addError('An active opportunity exists for the same project.');
                           
                           
                           }
                        
                        } 
                     }                                                            
               }
               
               }
               else{
                       for(Opportunity opp:opportunitylist){

                               opp.Is_Batch__c=false;
                               
                     }
               
               }
         
          }catch(Exception e){
          
          }
     }

                               
}